/*! \file wps.h
 * \brief WPS - WiFi Protected Setup
 *
 * Wi-Fi Protected Setup (WPS) is a standard for easy and secure wireless
 * network set up and connections. Using this standard, wireless clients
 * can associate with the WPS enabled access point by entering the same
 * PIN at client and AP end or by pushing a pushbutton on both. This eliminates
 * the need for manually entering the security configuration on the client side.
 *
 * Two methods that are supported by SDK are:
 *
 * \li PIN Method: In this method the same PIN (Personal Identification Number)
 * is entered on the wireless client and access point. The PIN can be static
 * or dynamically generated on any of the AP or wireless client.
 * \li PBC Method: in which the user simply has to push a button, either
 * an actual or virtual one, on both the AP and wireless client.
 *
 * \section wps_usage Usage
 * In a typical implementation WPS thread is started by calling \ref wps_start.
 * A valid initialized \ref wps_config structure needs to be passed to this
 * function. This structure contains a callback handler which is invoked by the
 * WPS thread on occurrence of various events. Once the WPS thread is started,
 * commands can be sent to it using \ref wps_connect function. Typically
 * these commands can be start PIN session, or start a pushbutton session. This
 * requires passing \ref wps_session_command structure that contains a valid
 * \ref wlan_scan_result that contains network information for a WPS enabled
 * wireless network. On successful WPS session, callback handler is invoked with
 * \ref WPS_SESSION_SUCCESSFUL event with \ref wlan_network structure that
 * contains all the security information for the network with which WPS
 * session was attempted. After this \ref wps_stop should be called to
 * terminate the WPS thread.
 *
 * \note WPS implementation lets application decide PIN policy. PIN could either
 * be generated by the application, or by the access point or can be statically
 * generated at device manufacturing time. \ref wps_generate_pin and \ref
 * wps_validate_pin utility functions can be used by the application to generate
 * and validate PIN.
 *
 * \note WPS thread internally uses multiple dynamic allocations. Please do not
 * reduce the heap size below 64KB if the application wishes to use WPS.
 *
 */

#ifndef WPS_API_H
#define WPS_API_H

#include <wlan.h>

/** wps log */
#ifdef CONFIG_WPA2_ENTP
#define WPS_LOG(...) wmlog("WPA2", ##__VA_ARGS__)
#else
#define WPS_LOG(...) wmlog("wps", ##__VA_ARGS__)
#endif

/** enum : WPS session commands */
enum wps_session_command {
	/** Command to start WPS PIN session */
	CMD_WPS_PIN = 0,
	/** Command to start WPS PBC session */
	CMD_WPS_PBC
};

/** enum : WPS events */
enum wps_event {
	/** WPS thread started */
	WPS_STARTED = 0,
	/** WPS PBC/PIN Session started */
	WPS_SESSION_STARTED,
	/** WPS PIN checksum failed */
	WPS_SESSION_PIN_CHKSUM_FAILED,
	/** WPS Session aborted */
	WPS_SESSION_ABORTED,
	/** WPS Session registration timeout */
	WPS_SESSION_TIMEOUT,
	/** WPS Session attempt successful */
	WPS_SESSION_SUCCESSFUL,
	/** WPS Session failed */
	WPS_SESSION_FAILED,
	/** WPS thread stopped */
	WPS_FINISHED
};

/** Enum that indicates type of WPS session
*   either a push button or a PIN based session is
*   determined by value fo this enum
*/
enum wps_session_types {
	/** WPS session is not active */
	WPS_SESSION_INACTIVE = 0xffff,
	/** WPS Push Button session active */
	WPS_SESSION_PBC = 0x0004,
	/** WPS PIN session active */
	WPS_SESSION_PIN = 0x0000,
};

/**
 * This struct is passed to wps_start(). The user must initialize it
 * with parameters as described inline.
 */
struct wps_config {
	/** Enrollee: 1, Registrar: 2, WiFi Direct mode:4 */
	uint8_t role;
	/** PIN Generator - Enrollee or Registrar */
	uint8_t pin_generator;
	/** version */
	uint8_t version;
	/** version */
	uint8_t version2;
	/** Device name */
	uint8_t device_name[32];
	/** Manufacture */
	uint8_t manufacture[64];
	/** Model name */
	uint8_t model_name[32];
	/** Model number */
	uint8_t model_number[32];
	/** Serial number */
	uint8_t serial_number[32];
	/** Config methods */
	uint16_t config_methods;
	/** Primary Device category*/
	uint16_t primary_dev_category;
	/** Primary Device subcategory*/
	uint16_t primary_dev_subcategory;
	/** RF bands */
	uint8_t rf_bands;
	/** OS Version */
	uint32_t os_version;
	/** WPS message max retry */
	uint8_t wps_msg_max_retry;
	/** WPS message timeout */
	uint32_t wps_msg_timeout;
	/** PIN length */
	uint16_t pin_len;
	/** WPS callback */
	int (*wps_callback) (enum wps_event event, void *data, uint16_t len);
};

/** Starts WPS thread and enables commands delivery
 *
 * \param wps_conf A pointer to WPS custom configuration
 *
 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
 */
int wps_start(struct wps_config *wps_conf);

/** Connect to WPS enabled AP
 *
 * Connect to a WPS enabled AP. This function is typically called whenever
 * the users pushes the wps button or enters wps pin.
 *
 * \param pbc Set to 1 if Push-button session is desired
 * \param pin Ignore if pbc is 1. If pbc is 0, this indicates the pin that
 * should be used. The pin can be 4 or 8 digits.
 * \param res The WPS enabled AP to connect to.
 *
 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
 */
int wps_connect(enum wps_session_command pbc, uint32_t pin,
			struct wlan_scan_result *res);

/** Generate 8 digit WPS PIN value with random number generator
 *
 * \param wps_pin Generated 8 digit WPS PIN value
 *
 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
 */
int wps_generate_pin(uint32_t *wps_pin);

/**Validate checksum of PIN
 *
 * \param wps_pin WPS PIN value
 *
 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
 **/
int wps_validate_pin(uint32_t wps_pin);

/** Deletes WPS thread and message queue
 *
 * \returns WM_SUCCESS if successful, -WM_FAIL otherwise
 */
int wps_stop();
#endif
